package com.chisheng.caa.pojo.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.lang.Nullable;

import java.io.Serializable;
import java.util.Objects;

@Data
@ApiModel("JSON 格式响应数据包装类")
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JsonResponse<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("状态码")
    protected Boolean status;

    @ApiModelProperty("响应码")
    protected ResponseCode code;

    @ApiModelProperty("消息")
    protected String message;

    @Nullable
    @ApiModelProperty("正文")
    protected T content;

    /**
     * 逻辑成功的响应对象工厂方法
     */
    public static <T> JsonResponse<T> success() {
        return getInstance(ResponseCode.SUCCESS, null, null);
    }

    /**
     * 逻辑成功的响应对象工厂方法
     */
    public static <T> JsonResponse<T> success(@Nullable T content) {
        return getInstance(ResponseCode.SUCCESS, null, content);
    }

    /**
     * 逻辑成功的响应对象工厂方法
     */
    public static <T> JsonResponse<T> success(ResponseCode code, @Nullable T content) {
        return getInstance(code, null, content);
    }

    /**
     * 逻辑失败的响应对象工厂方法
     */
    public static <T> JsonResponse<T> failure(@Nullable T content) {
        return getInstance(ResponseCode.FAILURE, null, content);
    }

    /**
     * 逻辑失败的响应对象工厂方法
     */
    public static <T> JsonResponse<T> failure(@Nullable String message) {
        return getInstance(ResponseCode.FAILURE, message, null);
    }

    /**
     * 逻辑失败的响应对象工厂方法
     */
    public static <T> JsonResponse<T> failure(ResponseCode code, @Nullable String message) {
        return getInstance(code, message, null);
    }

    /**
     * 简单工厂方法
     */
    public static <T> JsonResponse<T> getInstance(ResponseCode code, @Nullable String message, @Nullable T content) {
        message = Objects.requireNonNullElse(message, code.getReason());
        return new JsonResponse<>(code.getStatus(), code, message, content);
    }

}
